/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.upf.grupof.projectphotos.databases;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.xmldb.api.base.ResourceIterator;
import org.xmldb.api.base.ResourceSet;
import org.xmldb.api.base.XMLDBException;
import org.xmldb.api.modules.XMLResource;
import org.xmldb.api.modules.XQueryService;
import org.xmldb.api.modules.XUpdateQueryService;

/**
 *
 * @author fredi
 */
public class DBManager implements iDBManager {

    private static DBManager instance = new DBManager();
    private XmlDbDataSource datasource;
    private Properties aProperties;
    private final String properties = "query.properties";
    private boolean correct = true;

    public static DBManager getInstance() {
        return instance;
    }

    private DBManager() {
        datasource = XmlDbDataSource.getInstance();

        try {
            aProperties = loadProperties();
        } catch (IOException ex) {
            Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public iXmlDbDataSource getDataSource(){
        return datasource;
    }
    
    private Properties loadProperties() throws IOException {
        Properties dbprop = new Properties();
        InputStream is = iDBManager.class.getClassLoader().getResourceAsStream(properties);
        InputStreamReader isr = null;
        try {
            isr = new InputStreamReader(is, "UTF-8");
            dbprop.load(isr);
        } finally {
            if (isr != null) {
                isr.close();
            }
            if (is != null) {
                is.close();
            }
        }

        return dbprop;
    }

    public iDBActionResult execute(iDBAction aDBaction) {
        XQueryService service = null;
        XUpdateQueryService updateservice = null;
        String query;
        List<iPhoto> resultats = new ArrayList<iPhoto>();
        DBActionResult result = new DBActionResult();

        int fin = aDBaction.getActionId().indexOf(".");
        query = aDBaction.getActionId().substring(0, fin);
        try {
            if (query.equalsIgnoreCase("consulta")) {
                service = (XQueryService) datasource.getCollection().getService("XQueryService", "1.0");
            } else if (query.equalsIgnoreCase("update")) {
                updateservice = (XUpdateQueryService) datasource.getCollection().getService("XUpdateQueryService", "1.0");
            }
        } catch (XMLDBException ex) {
            Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
            result.setErrorMsg(ex.getMessage());
            result.setException(ex);
            return result;
        }

        //Si ha podido crear el servicio de Xquery,
        int fin2 = aDBaction.getActionId().indexOf(".", aDBaction.getActionId().indexOf(".")+1);
        String tipo = aDBaction.getActionId().substring(fin+1, fin2);
                  
        if (query.equalsIgnoreCase("consulta")) {
            MessageFormat frm = new MessageFormat(aProperties.getProperty(aDBaction.getActionId()));
            String xquery = "";
            String parameters = "(";
            String[] keywords = (String[]) aDBaction.getParameters();
            

            if((tipo.equalsIgnoreCase("foto"))||(tipo.equalsIgnoreCase("noticia"))){
                System.out.println("estem aquí, comprobant");
                for(int i=0; i<aDBaction.getParameters().length; i++){
                    parameters = parameters +
                             "\"" + keywords[i] + "\"";
                    if(!(i == aDBaction.getParameters().length-1))
                        parameters = parameters + ",";
                }
                parameters = parameters + ")";
                xquery = frm.format(new String[]{parameters});
            } else if (tipo.equalsIgnoreCase("ontologia")){
                xquery = frm.format(keywords);
            }
            ResourceSet rs = null;
            
            try {
                rs = service.query(xquery);
            } catch (XMLDBException ex) {
                Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
                result.setErrorMsg(ex.getMessage());
                result.setException(ex);
                return result;
            }
            
            ResourceIterator i = null;
            try {
                i=rs.getIterator();
            } catch (XMLDBException ex) {
                Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
                result.setErrorMsg(ex.getMessage());
                result.setException(ex);
                return result;
            }
            try {
                while(i.hasMoreResources()){
                    XMLResource r = (XMLResource) i.nextResource();
                    iPhoto photo=new Photo();
                    Handler ch = new Handler(photo);
                    r.getContentAsSAX(ch);
                    resultats.add(photo);
                }
            } catch (XMLDBException ex) {
                Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
                result.setErrorMsg(ex.getMessage());
                result.setException(ex);
                return result;
            }
            result.setResult(resultats);
            
            return result;

        } else if(query.equalsIgnoreCase("update")) {
            
            MessageFormat frm = new MessageFormat(aProperties.getProperty(aDBaction.getActionId()));      
            
            try {
                updateservice.update(frm.format(aDBaction.getParameters()));
            } catch (XMLDBException ex) {
                Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
                result.setErrorMsg(ex.getMessage());
                result.setException(ex);
                return result;
            }
        }
        return null;

    }
}
